package com.gframework.mybatis.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.Lang;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import org.springframework.lang.Nullable;

import com.gframework.mybatis.dao.mybatis.provider.core.ProviderPlusLanguageDriver;
import com.gframework.mybatis.dao.mybatis.provider.per.PrimaryDaoProvider;
import com.gframework.sqlparam.SqlParam;

/**
 * 表示具有唯一特性的数据库操作接口。通常代表的是主键，也就是说实现该接口的操作接口操作的表都是含有主键的。
 * 
 * @since 1.0.0
 * @author Ghwolf
 * @param <K> 唯一性字段类型，通常表示主键类型 ({@link Serializable}接口子类)
 * @param <T> 表对应实体类的类型 {@link Serializable}接口子类，必须是一个POJO类型.
 * 
 * @see IViewDao
 * @see ITableBasicDAO
 */
public interface IPrimaryDAO<K extends Serializable, T extends Serializable> extends IMybatisDAO<T> {

	/**
	 * 根据主键删除一条数据.
	 * 
	 * <p>本方法会根据主键删除一条数据。
	 * 
	 * @param id 要删除的数据主键，不能为null
	 * @return 返回删除的行数
	 */
	@DeleteProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int deleteById(K id);
	
	/**
	 * 根据主键以及额外一个条件删除一条数据. 使用 and 连接。
	 * 
	 * @param id 要删除的数据主键，不能为null
	 * @param p 另一个参数，可以为null
	 * @return 返回删除的行数
	 * 
	 * @see SqlParam
	 */
	@DeleteProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int deleteByIdCondition(@Param("id") K id, @Nullable com.gframework.sqlparam.Param p);
	/**
	 * 根据主键以及额外两个条件删除一条数据. 使用 and 连接。
	 * 
	 * @param id 要删除的数据主键，不能为null
	 * @param p1 第一个参数，可以为null
	 * @param p2 第二个参数，可以为null
	 * @return 返回删除的行数
	 * 
	 * @see SqlParam
	 */
	@DeleteProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int deleteByIdConditions(@Param("id") K id, @Nullable com.gframework.sqlparam.Param p1, @Nullable com.gframework.sqlparam.Param p2);

	/**
	 * 根据主键批量删除数据.
	 * 
	 * @param ids 要删除的主键的集合，不能为null
	 * @return 返回删除的行数
	 */
	@DeleteProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int deleteByIds(@Param("ids") Collection<K> ids);
	
	/**
	 * 根据主键以及额外一个条件批量删除数据. 使用 and 连接。
	 * 
	 * @param ids 要删除的主键的集合，不能为null
	 * @param p 另一个参数，可以为null
	 * @return 返回删除的行数
	 */
	@DeleteProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int deleteByIdsCondition(@Param("ids") Collection<K> ids, @Nullable com.gframework.sqlparam.Param p);
	
	/**
	 * 根据主键以及额外两个条件批量删除数据. 使用 and 连接。
	 * 
	 * @param ids 要删除的主键的集合，不能为null
	 * @param p1 第一个参数，可以为null
	 * @param p2 第二个参数，可以为null
	 * @return 返回删除的行数
	 */
	@DeleteProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int deleteByIdsConditions(@Param("ids") Collection<K> ids, @Nullable com.gframework.sqlparam.Param p1,
			@Nullable com.gframework.sqlparam.Param p2);

	/**
	 * 根据主键更新一条数据的非null字段.
	 * 
	 * @param vo 要更新的数据，不能为null必须有主键
	 * @return 返回更新的行数
	 */
	@UpdateProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int updateById(T vo);
	
	/**
	 * 根据主键更新一条数据的全部字段.
	 * 
	 * @param vo 要更新的数据，不能为null必须有主键
	 * @return 返回更新的行数
	 */
	@UpdateProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int updateAllColumnById(T vo);

	/**
	 * 根据主键查询一条数据.
	 * 
	 * @param id 要查询的数据主键，不能为null
	 * @return 返回数据对象
	 */
	@SelectProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public T findById(K id);
	
	/**
	 * 根据主键和一个额外条件查询一条数据. 使用 and 连接。
	 * 
	 * @param id 要查询的数据主键，不能为null
	 * @param p 另一个参数，可以为null
	 * @return 返回数据对象
	 */
	@SelectProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public T findByIdCondition(@Param("id") K id, @Nullable com.gframework.sqlparam.Param p);
	
	/**
	 * 根据主键和两个额外条件查询一条数据. 使用 and 连接。
	 * 
	 * @param id 要查询的数据主键，不能为null
	 * @param p1 第一个参数，可以为null
	 * @param p2 第二个参数，可以为null
	 * @return 返回数据对象
	 */
	@SelectProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public T findByIdConditions(@Param("id") K id, @Nullable com.gframework.sqlparam.Param p1, @Nullable com.gframework.sqlparam.Param p2);
	
	/**
	 * 根据主键批量查询数据.
	 * 
	 * @param ids 要查询的主键的集合，不能为null
	 * @return 返回结果过封装成List集合返回
	 */
	@SelectProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public List<T> findByIds(@Param("ids") Collection<K> ids);
	
	/**
	 * 根据主键和额外一个条件批量查询数据. 使用 and 连接。
	 * 
	 * @param ids 要查询的主键的集合，不能为null
	 * @param p 另一个参数，可以为null
	 * @return 返回结果过封装成List集合返回
	 */
	@SelectProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public List<T> findByIdsCondition(@Param("ids") Collection<K> ids, @Nullable com.gframework.sqlparam.Param p);
	
	/**
	 * 根据主键和额外两个条件批量查询数据. 使用 and 连接。
	 * 
	 * @param ids 要查询的主键的集合，不能为null
	 * @param p1 第一个参数，可以为null
	 * @param p2 第二个参数，可以为null
	 * @return 返回结果过封装成List集合返回
	 */
	@SelectProvider(PrimaryDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public List<T> findByIdsConditions(@Param("ids") Collection<K> ids, @Nullable com.gframework.sqlparam.Param p1, @Nullable com.gframework.sqlparam.Param p2);
}
